#!/usr/bin/env python3

# -*- coding: utf-8 -*-
# File Name: MarkdownExtension.py
# Author: bobo
# Created Time: 20241116

import re
import xml.etree.ElementTree as etree

from markdown.blockprocessors import BlockProcessor
from markdown.extensions import Extension
from markdown.inlinepatterns import InlineProcessor


class DelInlineProcessor(InlineProcessor):
    def handleMatch(self, m, data):
        el = etree.Element("del")
        el.text = m.group(1)
        return el, m.start(0), m.end(0)


class DelExtension(Extension):
    def extendMarkdown(self, md):
        DEL_PATTERN = r"[~|-]{2,}(.*?)[~|-]{2,}"  # like --del--, ~~del~~
        md.inlinePatterns.register(DelInlineProcessor(DEL_PATTERN, md), "del", 175)


class BoxBlockProcessor(BlockProcessor):
    RE_FENCE_START = r"^!{3,} *\n"  # start line, e.g., `   !!!! `
    # last non-blank line, e.g, '!!!\n  \n\n'
    RE_FENCE_END = r"\n *!{3,}\s*$"

    def test(self, parent, block):
        return re.match(self.RE_FENCE_START, block)

    def run(self, parent, blocks):
        original_block = blocks[0]
        # print("Box:", blocks)
        blocks[0] = re.sub(self.RE_FENCE_START, "", blocks[0])
        # print("Box:", blocks[0])

        # Find block with ending fence
        for block_num, block in enumerate(blocks):
            if re.search(self.RE_FENCE_END, block):
                # remove fence
                blocks[block_num] = re.sub(self.RE_FENCE_END, "", block)
                # render fenced area inside a new div
                e = etree.SubElement(parent, "div")
                e.set("style", "display: inline-block; border: 1px solid red;")
                self.parser.parseBlocks(e, blocks[0 : block_num + 1])
                # remove used blocks
                for i in range(0, block_num + 1):
                    blocks.pop(0)
                return True  # or could have had no return statement
        # No closing marker!  Restore and do nothing
        blocks[0] = original_block
        return False  # equivalent to our test() routine returning False


class BoxExtension(Extension):
    def extendMarkdown(self, md):
        md.parser.blockprocessors.register(BoxBlockProcessor(md.parser), "box", 175)


"""
样例
::: primary|secondary|success|danger|warning|info
:::

"""


class HedgeAlertBlockProcessor(BlockProcessor):
    RE_FENCE_START = r"^:{3}\s*primary\s*.*\n*|^:{3}\s*secondary\s*.*\n*|^:{3}\s*success\s*.*\n*|^:{3}\s*danger\s*.*\n*|^:{3}\s*warning\s*.*\n*|^:{3}\s*info\s*.*\n*"
    RE_FENCE_END = r"\n*:{3}$"

    icon_dict = {
        "primary": "info-circle",
        "secondary": "info-circle",
        "success": "info-circle",
        "danger": "warning",
        "warning": "warning",
        "info": "info-circle",
    }

    def test(self, parent, block):
        return re.match(self.RE_FENCE_START, block)

    def run(self, parent, blocks):
        # print(blocks)
        original_block = blocks[0]
        first_blocks = original_block.split()
        # print(first_blocks)
        if len(first_blocks) == 3:
            title = first_blocks[2]
        elif len(first_blocks) == 2:
            title = "Tip"
        else:
            return False
        blocks[0] = re.sub(self.RE_FENCE_START, "", blocks[0])
        # print(blocks[0])

        # Find block with ending fence
        for block_num, block in enumerate(blocks):
            # print(re.search(self.RE_FENCE_END, block), block)
            if re.search(self.RE_FENCE_END, block):
                # remove fence
                blocks[block_num] = re.sub(self.RE_FENCE_END, "", block)
                # render fenced area inside a new div
                e = etree.SubElement(parent, "div")
                icon_elm = etree.Element("i")
                strong_tag = etree.Element("strong")
                title_elm = etree.Element("p")
                class_value = "alert alert-{}"
                flag = False
                for key in [
                    "primary",
                    "secondary",
                    "success",
                    "danger",
                    "warning",
                    "info",
                ]:
                    if key in original_block:
                        e.set("class", class_value.format(key))
                        e.set("role", "alert")
                        icon_elm.set("class", "fa fa-{}".format(self.icon_dict[key]))
                        strong_tag.append(icon_elm)
                        span_elm = etree.Element("span")
                        span_elm.text = title
                        strong_tag.append(span_elm)
                        title_elm.append(strong_tag)
                        e.insert(0, title_elm)
                        flag = True
                        break
                if not flag:
                    return False
                self.parser.parseBlocks(e, blocks[0 : block_num + 1])
                # remove used blocks
                for i in range(0, block_num + 1):
                    blocks.pop(0)
                return True  # or could have had no return statement
        # No closing marker!  Restore and do nothing
        blocks[0] = original_block
        return False  # equivalent to our test() routine returning False


class HedgeAlertExtension(Extension):
    """
    生产Alert块
    """

    def extendMarkdown(self, md):
        md.parser.blockprocessors.register(
            HedgeAlertBlockProcessor(md.parser), "alert_hedge", 178
        )


"""
样例
>^>##red##|^>##yellow##|^>##green##|^>##blue##|^>##purple##|^>##black##
>或者github格式 ^>[!CAUTION]|^>[!WARNING]|^>[!IMPORTANT]|^>[!TIP]|^>[!NOTE]
>
"""


class BlossomAlertBlockProcessor(BlockProcessor):
    RE_FENCE_START = r"^>\s*##red##.*\n|^>\s*##yellow##.*\n"
    # RE_FENCE_END = r">\s*$"
    # RE_FENCE_START = r"^...red...*\n*|^>##yellow##\n*|^>##green##\n|^>##blue##\n|^>##purple##\n|^##black##\n|^>[!CAUTION]|^>[!WARNING]|^>[!IMPORTANT]|^>[!TIP]|^>[!NOTE] "

    RE_TILTLE = r"^>\s*##(\w+)##\s*(\w*)"
    key_dict = {
        "CAUTION": "danger",
        "red": "danger",
        "WARNING": "warning",
        "yellow": "warning",
        "IMPORTANT": "primary",
        "purple": "primary",
        "NOTE": "primary",
        "blue": "primary",
        "TIP": "secondary",
        "green": "success",
    }

    icon_dict = {
        "primary": "info-circle",
        "secondary": "info-circle",
        "success": "info-circle",
        "danger": "warning",
        "warning": "warning",
        "info": "info-circle",
    }

    def test(self, parent, block):
        ret = re.match(self.RE_FENCE_START, block)
        if ret:
            print("Blossom:", block)
        return ret

    def run(self, parent, blocks):
        print("blocks:", blocks)
        original_block = blocks[0]
        title_blocks = original_block.split("\n")[0]
        ret = re.match(self.RE_TILTLE, title_blocks)
        style, title = ret.groups()
        print("Blossom-title:", ret.groups())
        if title == "":
            title = "Tip"

        blocks[0] = re.sub(self.RE_FENCE_START, "", blocks[0])
        print("删除匹配头:", blocks[0])

        # 只有一个块，只处理blocks[0]
        # render fenced area inside a new div
        e = etree.SubElement(parent, "div")
        icon_elm = etree.Element("i")
        strong_tag = etree.Element("strong")
        title_elm = etree.Element("p")
        class_value = "alert alert-{}"
        flag = False
        if style in self.key_dict.keys():
            e.set("class", class_value.format(self.key_dict[style]))
            e.set("role", "alert")
            icon_elm.set(
                "class",
                "fa fa-{}".format(self.icon_dict[self.key_dict[style]]),
            )
            strong_tag.append(icon_elm)
            span_elm = etree.Element("span")
            span_elm.text = title
            strong_tag.append(span_elm)
            title_elm.append(strong_tag)
            e.insert(0, title_elm)
            flag = True
        if not flag:
            return False

        print("处理前：", id(blocks), blocks)
        line = [re.sub(r"^\s*>\s*", "", i) for i in blocks[0].split("\n")]
        new_block = []
        s = ""
        for i in line:
            if i == "":
                new_block.append(s)
                s = ""
            else:
                s = s + i
        new_len = len(new_block)

        blocks.pop(0)
        for i in range(0, new_len):
            blocks.insert(0, new_block[new_len - i - 1])

        # blocks[0] = re.sub(r"\n\s*>\n\s*>", "\n\n", blocks[0])
        # blocks[0] = re.sub(r"^\n\s*>", "", blocks[0])
        print("处理后：", id(blocks), blocks)
        self.parser.parseBlocks(e, blocks[0:new_len])

        # remove used blocks
        for i in range(0, new_len):
            blocks.pop(0)
        print("处理后2：", id(blocks), blocks)
        return True  # or could have had no return statement


class BlossomAlertExtension(Extension):
    """
    生产Alert块
    """

    def extendMarkdown(self, md):
        md.parser.blockprocessors.register(
            BlossomAlertBlockProcessor(md.parser), "alert_blossom", 178
        )
